package com.meihua.code.concurrent;


import org.omg.CORBA.TIMEOUT;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @program: leetcode
 * @description:
 * @author: meihua
 * @created: 2021/08/25 09:56
 */

public class PayService {

    private  ConcurrentHashMap <String,Boolean> map = new ConcurrentHashMap<>(1024);

    private  ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, 5, TimeUnit.MICROSECONDS, new LinkedBlockingDeque<>());

    private  final  static Logger logger= LoggerFactory.getLogger(PayService.class);


//    private final String KEY="count";
//    public boolean budgetDeduct(int consumption){
//        if (redisTemplate.opsForValue().get("a")==null){
//            //分布式锁  这里用 sync 模拟
//            synchronized (KEY){
//                if (redisTemplate.opsForValue().get("a")==null){
//                    redisTemplate.opsForValue().set("a", queryCount());
//                }
//            }
//        }
//        boolean success =false;
//        try {
//            if (redisTemplate.opsForValue().decrement("a",consumption)>0){
//                success = updateCount(consumption)>0;
//            }
//        }catch (Exception e){
//
//        }finally {
//            //未能成功扣减 更新缓存
//            if (!success){
//                //返还 或清空  ?  争议
//                redisTemplate.opsForValue().set("a", queryCount());
//            }
//        }
//        return success;
//    }
//    public int queryCount(){
//        //从db里查的值
//        return 99;
//    }
//    @Transaction
//    public int updateCount(int consumption){
//       //乐观锁
//       String sql= " update test set num =if(num-"+consumption+">=0,num-"+consumption+",num) where id =1;";
//       return 0;
//    }


     public ConsultResulet queryPaymentEnabled(String paymentType){
         logger.info(" 查询 {}: ",paymentType);
         try {
           //  ((int)Math.random()%100)+30)
             Thread.sleep(30);
             if(paymentType.hashCode()%2==0){
                 return new ConsultResulet(false,"500");
             }
         }catch (InterruptedException e){

         }
         return  new ConsultResulet(true);
     }

    public static void main(String[] args) {
        PayService payService = new PayService();
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(10, 10, 5, TimeUnit.MICROSECONDS, new LinkedBlockingDeque<>());

        for (int i=0;i<10;i++){
            List<String> list= new ArrayList<>(8);
            list.add("qq");
            list.add("wx");
            list.add("jd");
            list.add("zfb");
            list.add("rmb");
            list.add("工商银行");
            poolExecutor.execute(()->{
                logger.info("{}",payService.filterDisablePayment(list));
            });
        }

        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        logger.info("=================== 分割 ==================");
        for (int i=0;i<100;i++){
            List<String> list= new ArrayList<>(8);
            list.add("qq");
            list.add("wx");
            list.add("jd"+i);
            list.add("zfb");
            list.add("rmb"+i);
            list.add("工商银行");
            poolExecutor.execute(()->{
                logger.info("{}",payService.filterDisablePayment(list));
            });
        }
        poolExecutor.shutdown();

    }

     public List<String> filterDisablePayment(List<String> allPaymentList ){
         List<String> result = new CopyOnWriteArrayList<>();
         CountDownLatch count = new CountDownLatch(allPaymentList.size());
         long l = System.currentTimeMillis();
         for (String key:allPaymentList){
                 if (map.containsKey(key)&&map.get(key)){
                     result.add(key);
                     count.countDown();
                 }else if (!map.containsKey(key)){
                     executor.execute(()-> {
                         synchronized (key.intern()) {
                             if (map.containsKey(key) && map.get(key)) {
                                 result.add(key);
                                 count.countDown();
                             } else if (!map.containsKey(key)) {
                                 ConsultResulet consultResulet = queryPaymentEnabled(key);
                                 map.put(key, consultResulet.isEnable);
                                 if (consultResulet.isEnable) {
                                     result.add(key);
                                 }
                                 count.countDown();
                             }
                         }
                     });
                 } else {
                     count.countDown();
                 }
         }
         try {
             count.await(200, TimeUnit.MILLISECONDS);
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
         logger.info(" 耗时 {}: ms",System.currentTimeMillis()-l);
         return result;
     }


    class ConsultResulet{
        private boolean isEnable;
        private String errorCode;

        public ConsultResulet(boolean isEnable, String errorCode) {
            this.isEnable = isEnable;
            this.errorCode = errorCode;
        }

        public ConsultResulet(boolean isEnable) {
            this.isEnable = isEnable;
            this.errorCode="20000";
        }
    }

}
